﻿using System.Linq;
using System;
using NUnit.Framework;
using System.Transactions;
using ProjetoComperio.Framework.Web.Security;
using Action = ProjetoComperio.Framework.Web.Security.Action;
namespace ProjetoComperio.Test.ComperioFramework.Web.Security
{
    [TestFixture]
    public class ComperioMemberShipProviderTest
    {
        private ComperioMemberShipProvider provider;
        [TestFixtureSetUp]
        public void SetUp()
        {

            provider = new ComperioMemberShipProvider();
        }

        [Test]
        public void TestSendNotificationToComperioAdmin()
        {
            ComperioMemberShipProvider comperioMemberShipProvider = new ComperioMemberShipProvider();
            var fakeUser = new User();
            fakeUser.CreationDate = DateTime.Now;
            fakeUser.UserName = "Higor.Cesar";
            fakeUser.UserID = 1;
            comperioMemberShipProvider.SendNotificationToComperioAdmin(fakeUser);

        }


        /// <summary>
        /// This test should run only when it's data is in database
        /// </summary>
        public void TestValidatePassword()
        {
#warning implementar

        }

        /// <summary>
        /// This test should run if there is no data with the same value
        /// it can be used to test e-mail sender
        /// </summary>
        [Test]
        public void TestCreateUser()
        {
            var randomValue = +new Random().Next();
            var user = new global::ProjetoComperio.Framework.Web.Security.User();
            user.UserName = "visitante" + randomValue;
            user.Password = "vscp01" + randomValue;
            user.Email = "visitante@projetocomperio.org" + randomValue;

            user.Role = provider.RetrieveRole(ComperioMemberShipProvider.Roles.Student);
            user.PersonID = 1;  //new PersonBLLFacade().RetrievePersons().FirstOrDefault().PersonID;
            provider.CreateUser(user);
            Assert.IsTrue(user.UserID != 0);

        }

        #region RoleMethods

        [Test]
        [Category("lazy")]
        public void TestCreateRole_ValidRole()
        {
            Role testRole = new Role();
            testRole.Name = "TestRole1";
            using (TransactionScope transactionScope = new TransactionScope())
            {
                provider.CreateRole(testRole);
                Assert.NotNull(provider.RetrieveRole(testRole.Name));
                transactionScope.Dispose();
            }
        }
        [Test]
        [Category("lazy")]
        public void TestCreateRole_DuplicatedName_Should()
        {
            Role testRole = new Role();
            testRole.Name = "TestRole1";
            using (TransactionScope transactionScope = new TransactionScope())
            {
                provider.CreateRole(testRole);
                Assert.NotNull(provider.RetrieveRole(testRole.Name));
                transactionScope.Dispose();
            }
        }

        [Test]
        [Category("Lazy")]
        public void TestGetAllRoles()
        {
            ComperioMemberShipProvider provider = new ComperioMemberShipProvider();
            Assert.IsTrue(provider.RetrieveRoles() is IQueryable<Role>);
        }

        [Test]
        public void TestRetrieveRole_ExistentRole()
        {
            using (TransactionScope transactionScope = new TransactionScope())
            {
                Role roleToTest = new Role();
                roleToTest.Name = "roleTotest_1";
                provider.CreateRole(roleToTest);
                Assert.AreEqual(roleToTest.Name, provider.RetrieveRole(roleToTest.Name).Name);
                transactionScope.Dispose();

            }

        }

        [Test]
        [Category("Lazy")]
        public void TestRetrieveRole_EmptyName_ShouldNotReturn()
        {
            using (TransactionScope transactionScope = new TransactionScope())
            {
                Assert.Null(provider.RetrieveRole(""));
                transactionScope.Dispose();
            }

        }


        #endregion

        #region ActionMethods

        [Test]
        [Category("Lazy")]
        public void TestCreateAction()
        {
            using (TransactionScope transactionScope = new TransactionScope())
            {
                Action action = new Action();
                action.Name = "ac_01";
                var controller = new Controller();
                controller.Name = "c_01";
                controller.Description = "d_01";
                action.Controller = controller;
                provider.CreateAction(action);
                Assert.AreEqual(action.Name, provider.RetrieveActionByDescription(action.Controller.Name, action.Name).Name);
                transactionScope.Dispose();
            }

        }

        [Test]
        public void TestRetrieveActionByDescription()
        {

            Assert.NotNull(provider.RetrieveActionByDescription("Student", "Create"));
        }

        [Test]
        public void TestRetrieveActionsByRole()
        {
            Assert.NotNull(provider.RetrieveActionsByRole(provider.RetrieveRoles().FirstOrDefault()));
        }

        [Test]
        public void TestRetrieveUserRole()
        {
            Assert.AreEqual(1, provider.RetrieveUserRole("higorcesar").RoleID);

        }

        [Test]
        [Category("Lazy")]
        public void TestUserHasPermission_NonExistentUser()
        {
            using (TransactionScope transactionScope = new TransactionScope())
            {
                Action action = new Action();
                action.Name = "ac_01";
                var controller = new Controller();
                controller.Name = "c_01";
                controller.Description = "d_01";
                action.Controller = controller;
                provider.CreateAction(action);
                Assert.AreEqual(action.Name, provider.RetrieveActionByDescription(action.Controller.Name, action.Name).Name);
                transactionScope.Dispose();
                Assert.IsFalse(provider.UserHasPermission(controller.Name, action.Name, "anything"));
            }

        }

        [Test]
        public void TestUserHasPermission()
        {
            //inserir usuário, cadastrar permissão e verificar
            Assert.IsTrue(provider.UserHasPermission("Student", "Create", "higorcesar"));
        }



        #endregion

        #region Controllers

        [Test]
        public void TestRetrieveControllers()
        {
            Assert.IsTrue(provider.RetrieveControllers() is IQueryable<Controller>);
        }
        [Test]
        public void TestRetrieveController()
        {
            Assert.NotNull(provider.RetrieveController("Project"));

        }

        [Test]
        [Category("lazy")]
        public void TestCreateController_valid()
        {
            using (TransactionScope transactionScope = new TransactionScope())
            {
                Controller controller = new Controller();
                controller.Description = "ct_1";
                controller.Name = "ct_1";
                provider.CreateController(controller);
                Assert.AreEqual(controller.Name, provider.RetrieveController(controller.Name).Name);
                transactionScope.Dispose();
            }
        }


        #endregion

    }


}

